/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.stefanini.informacion_mundialista.ejbs;

import com.stefanini.informacion_mundialista_data.entities.Equipo;
import com.stefanini.informacion_mundialista_data.entities.Grupo;
import com.stefanini.informacion_mundialista_data.result.ValidacionEquipos;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author gbuitrago
 */
@LocalBean
@Stateless
public class EquipoManager {
    
    @PersistenceContext
    private EntityManager em;
    
    /**
     * Verifica si un equipo ya existe a partir de su nombre. Retorna true si el
     * equipo ya existe, false en caso contrario
     *
     * @param nombreEquipo
     * @return
     */
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) //para definir que no se genere trasaccion ya que no necesita
    public boolean verificarEquipoExistente(String nombreEquipo){
        try {
            Query q = em.createQuery("Equipo.findByNombre", Equipo.class);
            q.setParameter("nombre", nombreEquipo);
            
            q.getSingleResult();
            return true;
            
        } catch (NoResultException e) {
            Logger.getLogger(EquipoManager.class.getName()).log(Level.SEVERE,
                    "No se encontraron equipos con el nombre indicado");
            return false;
        } catch (Exception e) {
            Logger.getLogger(EquipoManager.class.getName()).log(Level.SEVERE,
                    "Error al verificar la existencia del equipo", e);
            return false;
        }    
    }
    
    
     @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)// 
    public int validarEquipos(boolean cabezaSerie, Integer grupoId) {
         try {
            StringBuilder sql = new StringBuilder();
            sql.append("SELECT CABEZA_SERIE cabezaSerie, COUNT(*) cantidad ");
            sql.append("FROM EQUIPO ");
            sql.append("WHERE GRUPO_ID = ? ");
            sql.append("GROUP BY CABEZA_SERIE ");
            
            Query q = em.createNativeQuery(sql.toString(), "validacionEquipoResult");
            q.setParameter(1, grupoId);
            List<ValidacionEquipos> result = q.getResultList();
            
            if((cabezaSerie && result.size() > 1)
                    || (result.size() == 1 && 
                            cabezaSerie 
                            && Boolean.TRUE.equals(result.get(0).getCabezaSerie()))) {
                return 1;
            } else if(result.size() >= 1) {
                
                for (ValidacionEquipos validacionEquipos : result) {
                    if(result.size() == 1 && !Boolean.TRUE.equals(validacionEquipos.getCabezaSerie())
                            && validacionEquipos.getCantidad() == 3 && !cabezaSerie) {
                        return 2;
                    } else if(result.size() == 2 && !Boolean.TRUE.equals(validacionEquipos.getCabezaSerie())
                            && validacionEquipos.getCantidad() == 3) {
                        return 3;
                    }
                }
            }
            
            return 0;
         } catch (Exception e) {
             Logger.getLogger(EquipoManager.class.getName()).log(Level.SEVERE,
                    "Error al validar el equipo", e);
            return -1;
         }
        
    }
    
        /**
     * Consulta todos los equipos disponibles en la base de datos
     *@param grupoIdFiltro
     * @return
     */
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)// 
    public List<Equipo> getAllEquipos(Integer grupoIdFiltro) {
        try {
            StringBuilder jpql = new StringBuilder();
            jpql.append("SELECT e FROM Equipo e ");
            
            if(grupoIdFiltro != null ) {
                jpql.append("WHERE e.grupoId.id =:GRUPO_ID ");
            }
            
            jpql.append("ORDER BY e.grupoId, e.nombre");
            
            Query q = em.createQuery(jpql.toString());

            if(grupoIdFiltro != null ) {
                q.setParameter("GRUPO_ID", grupoIdFiltro);
            }
            
            return q.getResultList();

        } catch (Exception e) {
            Logger.getLogger(EquipoManager.class.getName()).log(Level.SEVERE,
                    "Error al consultar los equipos", e);
            return new ArrayList<>();
        }
    }
 
        /**
     * Guarda un equipo en la base de datos
     * @param equipo
     * @param isEdit 
     * @return 
     *      true si el equipo fue guardado exitosamente, false en caso contrario
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) // requiere nueva transaccion ya que requiere hacer un commit
    public boolean guardarEquipo(Equipo equipo, boolean isEdit){
       try{
        if(isEdit) {
                equipo.setGrupoId(em.find(Grupo.class, equipo.getGrupoId().getId())); // para que me busque y luego actualice el grupo con el nuevo ID que aparece en Equipo
                em.merge(equipo);
        } else {
                em.persist(equipo);                
            }
            em.flush();
            return true;
       }catch (Exception e) {
           Logger.getLogger(EquipoManager.class.getName()).log(Level.SEVERE, "Error al guardar el equipo", e);
           return false;
       }
    }
    
    
    
    /**
     * Guarda un equipo en la base de datos
     * @param equipo 
     * @return 
     *      true si el equipo fue guardado exitosamente, false en caso contrario
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public boolean eliminarEquipo(Equipo equipo){
       try{
           equipo = em.merge(equipo); //pasa el Entity de no majeado a manejado
            em.remove(equipo);     //remueve el objeto            
            em.flush();
            return true;
       }catch (Exception e) {
           Logger.getLogger(EquipoManager.class.getName()).log(Level.SEVERE, "Error al eliminar el equipo", e);
           return false;
       }
    }
}
